#pragma once
#include <iostream>
#include <memory>
#include <algorithm>
#include <utility>
#include <string>
#include <cassert>
#include <typeinfo>
#include <unistd.h>

namespace Muduo
{
    class Any
    {
    public:
        Any():_content(nullptr){}
        template <typename T>
        Any(const T& val):_content(new placeholder<T>(val)){}
        Any(const Any&other):_content(other._content?other._content->clone():nullptr){}
        ~Any() {delete _content; }

        //获取对象保存的数据的指针
        template<typename T>
        T * get()
        {
            //类型和保存的类型必须一致
            assert(typeid(T) == _content->type());
            return &(dynamic_cast<placeholder<T>*>(_content)->_val);
        }
        Any & swap(Any & other)
        {
            std::swap(_content,other._content);
            return *this;
        }

        //赋值运算符的重载
        template <class T>
        Any & operator=(const T & val)
        {
            Any(val).swap(*this);
            return *this;
        }

        Any & operator=(Any other)
        {
            other.swap(*this);
            return *this;
        }
    private:
        class holder
        {
        public:
            virtual ~holder(){}
            virtual const std::type_info & type() = 0;
            virtual holder * clone() = 0;
        };

        template<class T>
        class placeholder: public holder
        {
        public:
            placeholder(const T & val):_val(val){}
            //获取子类存储的对象类型
            virtual  const std::type_info & type() {return typeid(T); }
            //针对当前对象克隆一个新的子类对象
            virtual holder * clone() { return new placeholder(_val);}
            T _val;
        };
        holder * _content;
    };
}